<template>
  <div :style="styleObj">
    <div class="mapBack" v-loading="mapLoading">
      <div style="color: '#fff">
        <div :style="lengedStyle" v-if="LegendShow">
          <div v-if="mapLvl > 2" style="height: 60" />
          <div v-else>
            <div class="rowstyle">
              <div class="colstyle">
                <div class="icon" style="background-color: #E4975C;" />
                <div class="name">佛教：</div>
                <div class="num">{{f_num}}</div>
              </div>
              <div class="colstyle">
                <div class="icon" style="background-color: #a3b9dd;" />
                <div class="name">道教：</div>
                <div class="num">{{d_num}}</div>
              </div>
            </div>
            <div class="rowstyle">
              <div class="colstyle">
                <div class="icon" style="background-color: #208112;" />
                <div class="name">伊斯兰教：</div>
                <div class="num">{{y_num}}</div>
              </div>
              <div class="colstyle">
                <div class="icon" style="background-color: #E2E2E2;" />
                <div class="name">天主教：</div>
                <div class="num">{{t_num}}</div>
              </div>
            </div>
            <div class="rowstyle">
              <div class="colstyle">
                <div class="icon" style="background-color: #F15D5D;" />
                <div class="name">基督教：</div>
                <div class="num">{{j_num}}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div :style="breadStyle">
        <span style="display:flex"><img src="@/assets/images/zhengce2.png" style="width:18px; height:18px;object-fit:contain" />当前视图：</span>
        <el-breadcrumb separator="/">
          <el-breadcrumb-item
            v-for="(item, index) in rgonNmGrp"
            :key="index"
            style="margin-top:1px"
          >
            <a v-if="rgonNmGrp.length !== index+1" style="color:#fff" @click="onChartClick(item, item.lvl)">{{item.name}}</a>
            <span v-else>{{item.name}}</span>
          </el-breadcrumb-item>
        </el-breadcrumb>
      </div>
      <div class="echartMap" ref="mapRef" :style="mapStyleObj"></div>
    </div>
  </div>
</template>
<script>
import { fetchStatisInfo, queryRlgJson, queryTraficlist } from "@/api/bigscreen";
import { mapState } from 'vuex';
export default {
  name: "chinaMap",
  props: {
    value: Object,
    ispreview: Boolean,
  },
  data() {
    return {
      optionsStyle: {}, // 样式
      echartsMapStyle: {},
      geoCoordMap: [], // 坐标点
      geoJson: null, // 行政区划编码
      seriesData: [],
      rgonSiteNumGrp: null,
      useLvl: 1, // 用户级别
      mapLvl: 1, // 地图级别
      rgonNmGrp: [{code: '1', name: '22', lvl: 1},{code: '2', name: '33', lvl: 1}], // 面包屑数据
      f_num: 0, // 佛道伊天基数量
      d_num: 0,
      y_num: 0,
      t_num: 0,
      j_num: 0,
      dataValue: [],
      chartInstance: null, // chart实例
      options: { // 配置
        tooltip: {
          trigger: 'item',
          position: function (pos, params, dom, rect, size) { // eslint-disable-line
            // 鼠标在左侧时 tooltip 显示到右侧，鼠标在右侧时 tooltip 显示到左侧。
            const compare = pos[0] < size.viewSize[0] / 2;
            if (compare) {
              return [pos[0] - 100, pos[1]];
            }
              return [pos[0] + 60, pos[1]];
          },
          formatter: function (params) { // eslint-disable-line
            if (params.value && typeof (params.value)[2] === "undefined") {
              return `${params.name}:${isNaN(params.value)  ? '' : params.value}`;
            }
            return `${params.name}:${params.value && !isNaN(params.value[2]) ? params.value[2] : ''}`;
          },
        },
        visualMap: {},
        geo: {},
        series: [],
      },
      mapLoading: false,
      linzhou: '1'
    };
  },
  computed: {
    ...mapState('user', ['userInfo']),
    styleObj() {
      return {
        position: this.ispreview ? "absolute" : "static",
        width: this.optionsStyle.width + "px",
        height: this.optionsStyle.height + "px",
        left: this.optionsStyle.left + "px",
        top: this.optionsStyle.top + "px",
      };
    },
    // 地图样式
    mapStyleObj() {
      return {
        left: this.echartsMapStyle.left + "px",
        top: this.echartsMapStyle.top + "px",
      }
    },
    // 图例样式
    lengedStyle() {
      return {
        position: 'relative',
        left: this.echartsMapStyle.LegendLeft + "px",
        top: this.echartsMapStyle.LegendTop + "px",
        transform: `scale(${this.echartsMapStyle.scale})`
      }
    },
    // 显示图例
    LegendShow() {
      return this.echartsMapStyle.LegendShow
    },
    // 地图大小
    mapSize() {
      return this.echartsMapStyle.mapSize
    },
    // 面包屑样式
    breadStyle() {
      return {
        position: 'absolute',
        right: this.echartsMapStyle.breadLeft + "px",
        top: this.echartsMapStyle.breadTop + "px",
        transform: `scale(${this.echartsMapStyle.breadScale})`,
        display: 'flex',
        color: '#fff',
        'font-size': '14px',
        'z-index': 99
      }
    },
  },
  watch: {
    value: {
      handler(val) {
        this.optionsStyle = val.position;
        this.echartsMapStyle = val.setup
        this.chartInstance.resize()
        this.editorOptions();
      },
      deep: true,
    },
    // rgonSiteNumGrp: {
    //   handler(val) {
    //     this.selectMarkerMap(val)
    //   },
    //   deep: true,
    // },
  },
  async mounted() {
    // 初始化数据
    this.useLvl = [this.userInfo.prov_cd, this.userInfo.city_cd, this.userInfo.zon_cd].filter(item => !!item).length // 用户级别
    this.mapLvl = [this.userInfo.prov_cd, this.userInfo.city_cd, this.userInfo.zon_cd].filter(item => !!item).length // 地图级别
    this.rgonNmGrp = this.userInfo.zon_cd ?
      [{code: this.userInfo.prov_cd || '', name: '河南全省', lvl: 1}, {code: this.userInfo.city_cd || '', name: this.userInfo.city_nm || '', lvl: 2}, {code: this.userInfo.zon_cd || '', name: this.userInfo.zon_nm || '', lvl: 3}] :
      this.userInfo.city_cd ? [{code: this.userInfo.prov_cd || '', name: '河南全省', lvl: 1}, {code: this.userInfo.city_cd || '', name: this.userInfo.city_nm || '', lvl: 2}] :
      [{code: this.userInfo.prov_cd || '', name: '河南全省', lvl: 1}] // 面包屑数据
    this.optionsStyle = this.value.position;
    this.echartsMapStyle = this.value.setup
    // 查询地图气泡数据
    const params = {
      prov_cd: this.userInfo.prov_cd || '',
      city_cd: this.userInfo.city_cd || '',
      zon_cd: this.userInfo.zon_cd || '',
    }
    let rgonSiteNumGrp = [];
    this.mapLoading = true
    const res = await fetchStatisInfo(params)
    this.mapLoading = false
    if(res.tx_status !== '00') return
    if (params && (params.city_cd || params.zon_cd)) {
      rgonSiteNumGrp = res.site_z_num_grp
    } else {
      rgonSiteNumGrp = res.site_c_num_grp
    }
    this.chartInstance = this.$echarts.init(this.$refs.mapRef);
    await this.searchJsonData();
    await this.selectMarkerMap(rgonSiteNumGrp);
    await this.editorOptions();
    this.chartInstance.setOption(this.options);
    this.chartInstance.on('click',this.onChartClick)
  },
  methods: {
    // 修改图表options属性
    editorOptions() {
      this.setOptionsVisualMap();
      this.setOptionsSeries();
      this.setOptionsGeo();
    },
    // visualMap
    setOptionsVisualMap() {
      if(this.linzhou === '2') return
      let mapMax = 500;
      let seriesIndex = [1];
      let mapColor = ['#61fffe', '#3345ff'];

      const visualMap = {
        show: false,
        min: 0,
        max: mapMax,
        left: 'left',
        top: 'bottom',
        text: ['高', '低'], // 文本，默认为数值文本
        calculable: true,
        seriesIndex,
        inRange: {
          color: mapColor // 浅蓝
        },
      }
      this.options.visualMap = visualMap
      this.chartInstance.setOption(this.options);
    },
    // geo
    setOptionsGeo() {
      const geo = {
        show: true,
        map: 'henan',
        layoutCenter: ['50%', '55%'], // 属性定义地图中心在屏幕中的位置，一般结合layoutSize 定义地图的大小
        layoutSize: this.mapSize + '%', //(parseInt(this.styleObj.width) / 800) * 100 + '%', //'60%',
        aspectScale: 0.75, // 长宽比
        regions: this.convertData(this.seriesData).map(element => ({
          name: element.name,
          itemStyle: {
            // areaColor: '#2B91B7',
            // areaColor: areaColorFun(element.name),
            color: '#2B91B7',
          },
        })),
        label: {
          normal: {
            show: false,
          },
          emphasis: {
            show: false,
          },
        },
        zoom: 1,
        roam: false, // 是否开启鼠标缩放和平移漫游
        itemStyle: {
          normal: {
            areaColor: '#021A3E', // 地图背景色
            borderColor: '#3fdaff',
            borderWidth: 1,
            shadowColor: 'rgba(63, 218, 255, 0.5)',
            shadowBlur: 30,
          },
          emphasis: {
            areaColor: '#2B91B7',
          },
        },
      }
      this.options.geo = geo
      this.chartInstance.setOption(this.options);
    },
    // series
    setOptionsSeries() {
      if(this.linzhou === '2') return
      const max = 480;
      const min = 9; // todo
      const maxSize4Pin = 100;
      const minSize4Pin = 40;
      let series = [
        {
          name: 'light',
          type: 'effectScatter', // 带有涟漪特效动画的散点（气泡）图。利用动画特效可以将某些想要突出的数据进行视觉突出
          coordinateSystem: 'geo', // 使用地理坐标系，通过 geoIndex 指定相应的地理坐标系组件
          symbol: 'circle',
          rippleEffect: { // 涟漪特效相关配置。
            period: 2,
            scale: 2.5,
            brushType: 'fill',
          },
          data: this.convertData(this.seriesData),
          symbolSize: (val) => {
            return this.mapLvl > 1 ? val[2] / 2 > 45 ? 45 : val[2] / 2 :
            val[2] / 12 > 45 ? 45 : val[2] / 12;
          },
          label: {
            normal: {
              formatter: '{b}',
              position: 'right',
              show: false,
            },
            emphasis: {
              show: false,
            },
          },
          itemStyle: {
            normal: {
              color: '#09fdf2',
            },
          },
        },
        {
          type: 'map', // 当设定了 geoIndex 后，series-map.map 属性，以及 series-map.itemStyle 等样式配置不再起作用，而是采用 geo 中的相应属性。
          map: 'henan',
          geoIndex: 0,
          aspectScale: 0.75, // 长宽比
          showLegendSymbol: false, // 存在legend时显示
          label: {
            normal: {
              show: false,
            },
            emphasis: {
              show: false,
              textStyle: {
                color: '#fff',
              },
            },
          },
          itemStyle: {
            normal: {
              areaColor: '#031525',
              borderColor: '#3B5077',
            },
            emphasis: {
              areaColor: '#2B91B7',
            },
          },
          animation: false,
          data: this.seriesData,
        },
        {
          name: '点',
          type: 'scatter',
          coordinateSystem: 'geo',
          symbol: 'pin',
          symbolSize: function (val) { // eslint-disable-line
            const a = (maxSize4Pin - minSize4Pin) / (max - min);
            let b = minSize4Pin - (a * min);
            b = maxSize4Pin - (a * max);
            return val[2] > -1 ? 65 : null;
          },
          label: {
            normal: {
              show: true,
              textStyle: {
                color: '#fff',
                fontSize: 10,
              },
              height: 12,
              lineHeight: 12,
              // position: 'bottom',
              // padding: [3, 0],
              formatter: function (params) { // eslint-disable-line
                if (typeof (params.value)[2] === "undefined") {
                  return `${params.name.replace('市','').replace('区','').replace('县','')}\n${params.value}`;
                }
                  return `${params.name.replace('市','').replace('区','').replace('县','')}\n${params.value[2]}`;
              },
            },
          },
          itemStyle: {
            normal: {
              // color: '#b142c5', // 标志颜色
              color(params) {
                if (params.name === '佛教') {
                  return '#FF7575';
                } else if (params.name === '道教') {
                  return '#0677B7';
                } else if (params.name === '伊斯兰教') {
                  return '#0C817A';
                } else if (params.name === '天主教') {
                  return '#FFC107';
                } else if (params.name === '基督教') {
                  return '#9C27B0';
                }
                return '#b142c5';
              },
            },
          },
          zlevel: 6,
          data: this.mapLvl === 3 ? this.convertData(this.dataValue) : this.convertData(this.seriesData),
        },
      ]
      this.options.series = series
      this.chartInstance.setOption(this.options);

    },
    // 处理坐标点
    centerFn(point, type) {
      const center = point && point.sub_rgon_center ? JSON.parse(point.sub_rgon_center) : [];
      const name = point? point.sub_rgon_nm : '';

      let lngf = (center[0] - 0.03).toFixed(6);
      let latf = (center[1] + 0.02).toFixed(6);

      let lngd = (center[0] + 0.04).toFixed(6);
      let latd = (center[1] + 0.025).toFixed(6);

      let lngy = (center[0] + 0.05).toFixed(6);
      let laty = (center[1] - 0.016).toFixed(6);

      let lngt = (center[0] + 0.01).toFixed(6);
      let latt = (center[1] - 0.05).toFixed(6);

      let lngj = (center[0] - 0.03).toFixed(6);
      let latj = (center[1] - 0.02).toFixed(6);
      if (['上街区', '老城区', '西工区', '涧西区', '吉利区', '廛河回族区', '魏都区', '卫滨区', '凤泉区', '牧野区', '北关区', '殷都区',
      '解放区', '中站区', '石龙区', '禹王台区', '义马市', '鼓楼区'].includes(name)) {
        lngf = (center[0] - 0.012).toFixed(6);
        latf = (center[1] + 0.01).toFixed(6);

        lngd = (center[0] + 0.02).toFixed(6);
        latd = (center[1] + 0.006).toFixed(6);

        lngy = (center[0] + 0.028).toFixed(6);
        laty = (center[1] - 0.016).toFixed(6);

        lngt = (center[0] + 0.01).toFixed(6);
        latt = (center[1] - 0.03).toFixed(6);

        lngj = (center[0] - 0.014).toFixed(6);
        latj = (center[1] - 0.02).toFixed(6);
      }

      if (type === 'f') {
        return JSON.stringify([lngf, latf]);
      } else if (type === 'd') {
        return JSON.stringify([lngd, latd]);
      } else if (type === 'y') {
        return JSON.stringify([lngy, laty]);
      } else if (type === 't') {
        return JSON.stringify([lngt, latt]);
      }

      return JSON.stringify([lngj, latj]);
    },
    // 处理数据
    convertData(data1) {
      let point = {};
      if (this.mapLvl === 3) {
        point = this.geoCoordMap[0]; // 对应值的坐标点
      }
      const dataTemp = [{
        sub_rgon_center: this.centerFn(point, 'f'),
        sub_rgon_nm: "佛教"
      },{
        sub_rgon_center: this.centerFn(point, 'd'),
        sub_rgon_nm: "道教"
      },{
        sub_rgon_center: this.centerFn(point, 'y'),
        sub_rgon_nm: "伊斯兰教"
      },{
        sub_rgon_center: this.centerFn(point, 't'),
        sub_rgon_nm: "天主教"
      },{
        sub_rgon_center: this.centerFn(point, 'j'),
        sub_rgon_nm: "基督教"
      }];

      const res = [];
      if (data1 && data1.length > 0) {
        for (let i = 0; i < data1.length; i += 1) {
          let geoCoord = this.geoCoordMap ? this.geoCoordMap.filter(item => data1[i].name === item.sub_rgon_nm)[0] : ''; // 对应值的坐标点
          if (this.mapLvl === 3) {
            geoCoord = dataTemp ? dataTemp.filter(item => data1[i].name === item.sub_rgon_nm)[0] : ''; // 对应值的坐标点
          }
          if (geoCoord && geoCoord.sub_rgon_center) {
            res.push({
              name: data1[i].name,
              value: JSON.parse(geoCoord.sub_rgon_center).concat(data1[i].value), // 新值= 坐标+旧值
              nameCode: data1[i].nameCode,
            });
          }
        }
      }
      return res;
    },
    // 初始化地图和坐标点
    async searchJsonData() {
      const mapLvl = this.mapLvl
      const rgonNmGrp = this.rgonNmGrp
      this.mapLoading = true
      const res = await queryRlgJson({
        sup_rgon_nm: mapLvl === 3 ? rgonNmGrp[1].name : '',
        rgon_nm: mapLvl === 3 ?  this.userInfo.zon_nm : mapLvl === 2 ? this.userInfo.city_nm : this.userInfo.prov_nm,
        rgon_cd: mapLvl === 3 ?  this.userInfo.zon_cd : mapLvl === 2 ? this.userInfo.city_cd : this.userInfo.prov_cd,
      })
      this.mapLoading = false
      if(res.tx_status !== '00') return
      this.geoCoordMap = res.sub_inf // 坐标点
      this.geoJson = res.rgon_inf ? JSON.parse(res.rgon_inf) : null // 行政区划编码
      res.rgon_inf && this.$echarts.registerMap('henan', res.rgon_inf);
    },
    // 初始化数据
    selectMarkerMap(rgonSiteNumGrp) {
      const temData = [];
      let dataValue = [];
      if (rgonSiteNumGrp && rgonSiteNumGrp.length > 0) {
        let f_num = 0;
        let d_num = 0;
        let y_num = 0;
        let t_num = 0;
        let j_num = 0;
        rgonSiteNumGrp.forEach(item => {
          temData.push({
            name: item.zon_cd ? item.zon_cd_desc || '' : item.city_cd_desc || '',
            value: Number(item.site_num || 0),
            nameCode: item.zon_cd ? item.zon_cd || '' : item.city_cd || '',
          });
          f_num += Number(item.bdhsm_site_num);
          d_num += Number(item.tsm_site_num);
          y_num += Number(item.islm_site_num);
          t_num += Number(item.ctlc_site_num);
          j_num += Number(item.chrst_site_num);
        });
        if (this.mapLvl === 3) {
          dataValue = [{
            name: "佛教",
            value: Number(f_num || 0),
            nameCode: '0200',
          }, {
            name: "道教",
            value: Number(d_num || 0),
            nameCode: '0200',
          }, {
            name: "伊斯兰教",
            value: Number(y_num || 0),
            nameCode: '0200',
          }, {
            name: "天主教",
            value: Number(t_num || 0),
            nameCode: '0200',
          }, {
            name: "基督教",
            value: Number(j_num || 0),
            nameCode: '0200',
          }];
        }
        this.seriesData = temData
        this.f_num = f_num
        this.d_num = d_num
        this.y_num = y_num
        this.t_num = t_num
        this.j_num = j_num
        this.dataValue = dataValue
      }
    },
    // 点击面包屑, 下钻
    async onChartClick(e, lvl) {
      if (this.mapLvl < 3 || typeof(lvl) === 'number') {
        let newRgon = typeof(lvl) === 'number' ? this.rgonNmGrp.slice(0, lvl) : e.data ? [...this.rgonNmGrp, {code: e.data.nameCode, name: e.data.name, lvl: this.mapLvl + 1}].filter(item => !!item) : [];
        this.mapLoading = true
        const res = await queryRlgJson({
          sup_rgon_nm: typeof(lvl) === 'number' ? '' : this.mapLvl === 2 ? this.rgonNmGrp[1].name : '',
          rgon_nm: typeof(lvl) === 'number' && lvl === 1 ? this.userInfo.prov_nm : e.name,
          rgon_cd:  typeof(lvl) === 'number' ? e.code : e.data.nameCode,
        })
        this.mapLoading = false
        if(res.tx_status !== '00') return
        newRgon = typeof(lvl) === 'number' ? this.rgonNmGrp.slice(0, lvl) : [...this.rgonNmGrp, {code: e.data.nameCode, name: res.rgon_nm || '', lvl: this.mapLvl + 1}].filter(item => !!item);
        // 改变数据
        this.geoCoordMap = res.sub_inf // 坐标点
        this.geoJson = res.rgon_inf ? JSON.parse(res.rgon_inf) : null // 行政区划编码
        this.mapLvl = typeof(lvl) === 'number' ? lvl : this.mapLvl + 1
        this.rgonNmGrp = newRgon
        this.$echarts.registerMap('henan', this.geoJson);
        this.handleCallBack(newRgon, e.name);
        // 河南省林州市
        this.linzhou = '1'
        if (e.name === '林州市') {
          this.linzhou = '2'
          this.onChartHeatmap();
        }
      }
    },
    // 下钻查询
    async handleCallBack(e, nm) {
      if (e && e.length > 0) {
        const value = {
          prov_cd: e && e.length > 0 ? e[0].code : '',
          city_cd: e && e.length > 1 ? e[1].code : '',
          zon_cd: e && e.length > 2 ? e[2].code : '',
          str_cd: e && e.length > 3 ? e[3].code : '',
        }
        let rgonSiteNumGrp = [];
        this.mapLoading = true
        const res = await fetchStatisInfo({...value, hb_big_screen: "1"})
        this.mapLoading = false
        if(res.tx_status !== '00') return
        if (value && (value.city_cd || value.zon_cd)) {
          rgonSiteNumGrp = res.site_z_num_grp
        } else {
          rgonSiteNumGrp = res.site_c_num_grp
        }

        await this.selectMarkerMap(rgonSiteNumGrp)
        await this.editorOptions();

      }
    },
    // 林州市
    onChartHeatmap(){
      queryTraficlist({
        prov_cd: '410000000000',
        city_cd: '410500000000',
        zon_cd: '410581000000',
      }).then((res) => {
        if (res && res.tx_status === '00') {
          const data = [];
          res && res.trafic_list && res.trafic_list.forEach(item => {
            const coord = item.coord ? JSON.parse(item.coord) : [];
            if (coord instanceof Array && item.num) {
              data.push(coord.concat(item.num * 1));
            }
          });
          // 林州市
          let areaData = [];
          data.map(item => { // 扩大热力图效果
            areaData.push(...new Array(3).fill(item));
          });

          let series = [
            {
              type: 'map', // 当设定了 geoIndex 后，series-map.map 属性，以及 series-map.itemStyle 等样式配置不再起作用，而是采用 geo 中的相应属性。
              map: 'henan',
              geoIndex: 0,
              aspectScale: 0.75, // 长宽比
              showLegendSymbol: false, // 存在legend时显示
              label: {
                normal: {
                  show: false,
                },
                emphasis: {
                  show: false,
                  textStyle: {
                    color: '#fff',
                  },
                },
              },
              itemStyle: {
                normal: {
                  areaColor: '#2B91B7',
                  borderColor: '#3B5077',
                },
                emphasis: {
                  areaColor: '#2B91B7',
                },
              },
              animation: false,
              data: this.seriesData,
            },
            {
              name: 'AQI',
              type: 'heatmap',
              coordinateSystem: 'geo',
              // blurSize: 40,
              data: areaData,
            }
          ];

          this.options.series = series

          const visualMap = {
            show: false,
            min: 0,
            max: Math.max(...data.map(item => item[2])),
            left: 'left',
            top: 'bottom',
            text: ['高', '低'], // 文本，默认为数值文本
            calculable: true,
            seriesIndex: null,
            inRange: {
              color: ['#ff4601', '#fffc00', '#87cffa'] // 浅蓝
            },
          }
          this.options.visualMap = visualMap
          this.chartInstance.setOption(this.options);
        }
      })
    }
  }
};
</script>
<style lang="less" scoped>
.echartMap {
  width: 100%;
  height: 100%;
  position: absolute;
}
.echarts {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.mapBack {
  height: 100%;
  // background-image: url('/img/hnBigScreen/map.png');
  // background-position: center;
  // background-repeat: no-repeat;
  // background-size: 138% 94%;
  // background-position-x: -116px;
  // background-position-y: 122px;
  // position: relative;
  // top: -65px;
  /deep/.el-breadcrumb__inner {
    color: #fff;
  }
  /deep/.el-loading-mask {
    background-color: rgba(0,0,0,0.5)
  }
}

.rowstyle {
  display: flex;
  .colstyle {
    color: #fff;
    display: flex;
    width: 150px;
    margin: 6px 0;
    .icon{
      width: 10px;
      height: 10px;
      border-radius: 50%;
      margin: 5px;
    }
    .name {
      font-size: 16px;
    }
    .num {
      font-size: 16px;
    }
  }

}
</style>
